# coding:utf-8
# writingtime: 2022-6-30
# author: caozihao
import os
from Utilities.AutoGetOperator.selectionMethod.selectPackage import get_func


Operator_IVQ_ROFS=get_func('E:\DecisionSystem\Operators\OperationOperators\OperatorIVQROF.py','Operator_IVQ_ROFS')

class Einstein(Operator_IVQ_ROFS):


    def add(self, a1, a2, q=0, *waste1, **waste2):
        """
            funciton    : Einstein的 和 运算
            a          : 一个模糊集, 形式:（[x,y]，[x,y]）
            b        : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 加法结果, 形式:（[x,y]，[x,y]）
        """
        u1 = a1[0]
        u2 = a2[0]
        v1 = a1[1]
        v2 = a2[1]

        if q <= 0:
            q = self.q

        x = [
                ((u1[0] ** q + u2[0] ** q) ** (1 / q))/((1 + (u1[0] ** q) * (u2[0] ** q)) ** (1/q)),
                ((u1[1] ** q + u2[1] ** q) ** (1 / q)) / ((1 + (u1[1] ** q) * (u2[1] ** q)) ** (1 / q))
        ]

        y = [
                (v1[0] * v2[0]) / ((1 + (1 - v1[0] ** q) * (1 - v2[0] ** q)) ** (1 / q)),
                (v1[1] * v2[1]) / ((1 + (1 - v1[1] ** q) * (1 - v2[1] ** q)) ** (1 / q))
        ]

        return (x, y)

    def multi(self, a1, a2, q=0, *waste1, **waste2):
        '''
        function: Einstein的乘法运算
        :param a1: 区间值广义正交模糊集 形式:（[x,y]，[x,y]）
        :param a2: 区间值广义正交模糊集 形式:（[x,y]，[x,y]）
        :param q: q
        :return:
        '''
        u1 = a1[0]
        u2 = a2[0]
        v1 = a1[1]
        v2 = a2[1]

        if q <= 0:
            q = self.q

        x = [
            (u1[0] * u2[0]) / ((1 + (1 - u1[0] ** q) * (1 - u2[0] ** q)) ** (1 / q)),
            (u1[1] * u2[1]) / ((1 + (1 - u1[1] ** q) * (1 - u2[1] ** q)) ** (1 / q))
        ]

        y = [
            ((v1[0] ** q + v2[0] ** q) ** (1 / q)) / ((1 + (v1[0] ** q) * (v2[0] ** q)) ** (1 / q)),
            ((v1[1] ** q + v2[1] ** q) ** (1 / q)) / ((1 + (v1[1] ** q) * (v2[1] ** q)) ** (1 / q))
        ]

        return (x, y)

    def kmulti(self, a, k, q=0, *waste1, **waste2):
        '''
        Einstein的数乘运算
        :param a: 区间值广义正交模糊集 形式:（[x,y]，[x,y]）
        :param k: 乘数
        :param q: q
        :return:
        '''

        u = a[0]
        v = a[1]

        if q <= 0:
            q = self.q

        x = [
            (((1 + u[0] ** q) ** k - (1 - u[0] ** q) ** k) ** (1 / q)) / (((1 + u[0] ** q) ** k + (1 - u[0] ** q) ** k) ** (1 / q)),
            (((1 + u[1] ** q) ** k - (1 - u[1] ** q) ** k) ** (1 / q)) / (((1 + u[1] ** q) ** k + (1 - u[1] ** q) ** k) ** (1 / q))
        ]

        y = [
            ((2 * ((v[0]) ** q) ** k) ** (1 / q)) / (((2 - v[0] ** q) ** k + (v[0] ** q) ** k) ** (1 / q)),
            ((2 * ((v[1]) ** q) ** k) ** (1 / q)) / (((2 - v[1] ** q) ** k + (v[1] ** q) ** k) ** (1 / q))
        ]

        return (x, y)

    def pow(self, a, k, q=0, *waste1, **waste2):
        '''
        Einstein的数乘运算
        :param a: 区间值广义正交模糊集 形式:（[x,y]，[x,y]）
        :param k: 指数
        :param q: q
        :return:
        '''
        u = a[0]
        v = a[1]

        if q <= 0:
            q = self.q
        x = [
            ((2 * ((u[0]) ** q) ** k) ** (1 / q)) / (((2 - u[0] ** q) ** k + (u[0] ** q) ** k) ** (1 / q)),
            ((2 * ((u[1]) ** q) ** k) ** (1 / q)) / (((2 - u[1] ** q) ** k + (u[1] ** q) ** k) ** (1 / q))
        ]

        y = [
            (((1 + v[0] ** q) ** k - (1 - v[0] ** q) ** k) ** (1 / q)) / (((1 + v[0] ** q) ** k + (1 - v[0] ** q) ** k) ** (1 / q)),
            (((1 + v[1] ** q) ** k - (1 - v[1] ** q) ** k) ** (1 / q)) / (((1 + v[1] ** q) ** k + (1 - v[1] ** q) ** k) ** (1 / q))
        ]

        return (x, y)

class EinsteinA(Einstein):

    def getResult(self):
        '''
        function：基础的算数平均公式
        :return: AA公式计算的结果
        '''
        result=self.data_list[0]
        for i in range(1,len(self.data_list)):
            result=self.add(result,self.data_list[i])
        result=self.kmulti(result,1/len(self.data_list))

        return result

class EinsteinGA(Einstein):

    def getResult(self):
        '''
        function：基础的算数平均公式
        :return: AA公式计算的结果
        '''
        result = self.data_list[0]
        for i in range(1, len(self.data_list)):
            result = self.multi(result, self.data_list[i])
        result = self.pow(result, 1 / len(self.data_list))

        return result

class EinsteinWA(Einstein):

    def getResult(self):
        '''
        function：基础的加权算数平均公式
        :return: WAA公式计算的结果
        '''
        result = self.kmulti(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.kmulti(self.data_list[i],self.weight_list[i])
            result = self.add(result, temp)

        return result

class EinsteinWGA(Einstein):

    def getResult(self):
        '''
        function：基础的加权几何平均公式
        :return: WAA公式计算的结果
        '''
        result = self.pow(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.pow(self.data_list[i],self.weight_list[i])
            result = self.multi(result, temp)

        return result

class EinsteinOWA(Einstein):

    def getResult(self):
        '''
        function：基础的有序加权算数平均公式
        :return: OWAA公式计算的结果
        '''
        # 将 数据集备份，将类中数据集属性 替换为 排序后的数据集
        data_list = self.data_list
        self.data_list = self.sortdata()

        result = self.kmulti(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.kmulti(self.data_list[i],self.weight_list[i])
            result = self.add(result, temp)

        # 还原数据集
        self.data_list = data_list
        return result

if __name__ == '__main__':
    data_list=[([0.31, 0.24], [0.73, 0.72]), ([0.97, 0.12], [0.12, 0.05]),
    ([0.8, 0.52], [0.73, 0.15]), ([0.91, 0.49], [0.42, 0.47]),([0.95, 0.06], [0.19, 0.1])]
    weight_list=[0.1, 0.2, 0.3, 0.1, 0.3],
    einstein = EinsteinA(data_list).getResult()
    print(einstein)
    # Pa = GA(list1)
    # Pa = WA(list1,weight_list)
    # Pa = WGA(list1,weight_list)
    # Pa = OWA(list1,weight_list)
    # print(einstein.pow(data_list[0], 3))
